using System;

namespace IBNet
{
   /// <summary>
   /// Execution details returned by Interactive Brokers. This class is immutable.
   /// </summary>
   public class Execution
   {
      #region Private Variables

      private readonly string accountNumber;
      private readonly int clientId;
      private readonly string exchange;
      private readonly string executionId;
      private readonly int liquidation;
      private readonly int orderId;
      private readonly int permId;
      private readonly decimal fillPrice;
      private readonly int shares;
      private readonly ExecutionSide side;
      private readonly string time;
      private readonly int cumulativeQuantity;
      private readonly decimal averagePrice;

      #endregion

      #region Constructors

      /// <summary>
      /// Full Constructor
      /// </summary>
      /// <param name="orderId">The order id.</param>
      /// <param name="clientId">TWS orders have a fixed client id of "0."</param>
      /// <param name="executionId">Unique order execution id.</param>
      /// <param name="time">The order execution time.</param>
      /// <param name="accountNumber">The customer account number.</param>
      /// <param name="exchange">Exchange that executed the order.</param>
      /// <param name="side">Specifies if the transaction was a sale or a purchase.</param>
      /// <param name="shares">The number of shares filled.</param>
      /// <param name="price">The order execution price.</param>
      /// <param name="permId">The TWS id used to identify orders, remains the same over TWS sessions.</param>
      /// <param name="liquidation">Identifies the position as one to be liquidated last should the need arise.</param>
      /// <param name="cumulativeQuantity">Cumalative quantity.</param>
      /// <param name="averagePrice">Average price.</param>
      public Execution(int orderId, int clientId, string executionId, string time, 
         string accountNumber, string exchange, ExecutionSide side, int shares, 
         decimal price, int permId, int liquidation, int cumulativeQuantity, 
         decimal averagePrice)
      {
         this.orderId = orderId;
         this.clientId = clientId;
         this.executionId = executionId;
         this.time = time;
         this.accountNumber = accountNumber;
         this.exchange = exchange;
         this.side = side;
         this.shares = shares;
         this.fillPrice = price;
         this.permId = permId;
         this.liquidation = liquidation;
         this.cumulativeQuantity = cumulativeQuantity;
         this.averagePrice = averagePrice;
      }

      #endregion

      #region Properties

      /// <summary>
      /// The customer account number.
      /// </summary>
      public string AccountNumber { get { return accountNumber; } }

      /// <summary>
      /// The id of the client that placed the order.
      /// </summary>
      /// <remarks>TWS orders have a fixed client id of "0."</remarks>
      public int ClientId { get { return clientId; } }

      /// <summary>
      /// Exchange that executed the order.
      /// </summary>
      public string Exchange { get { return exchange; } }

      /// <summary>
      /// Unique order execution id.
      /// </summary>
      public string ExecutionId { get { return executionId; } }

      /// <summary>
      /// Identifies the position as one to be liquidated last should the need arise.
      /// </summary>
      public int Liquidation { get { return liquidation; } }

      /// <summary>
      /// The order id. 
      /// </summary>
      /// <remarks>TWS orders have a fixed order id of "0."</remarks>
      public int OrderId { get { return orderId; } }

      /// <summary>
      /// The TWS id used to identify orders, remains the same over TWS sessions.
      /// </summary>
      public int PermId { get { return permId; } }

      /// <summary>
      /// The order execution price.
      /// </summary>
      public decimal FillPrice { get { return fillPrice; } }

      /// <summary>
      /// The number of shares filled.
      /// </summary>
      public int Shares { get { return shares; } }

      /// <summary>
      /// Specifies if the transaction was a sale or a purchase.
      /// </summary>
      /// <remarks>Valid values are:
      /// <list type="bullet">
      /// <item>Bought</item>
      /// <item>Sold</item>
      /// </list>
      /// </remarks>
      public ExecutionSide Side { get { return side; } }

      /// <summary>
      /// The order execution time.
      /// </summary>
      public string Time { get { return time; } }

      /// <summary>
      /// Cumulative Quantity
      /// </summary>
      public int CumulativeQuantity { get { return cumulativeQuantity; } }

      /// <summary>
      /// Average Price
      /// </summary>
      public decimal AveragePrice { get { return averagePrice; } }

      #endregion
   }
}